/*
* Copyright (C) 2020 ~ 2024 chaigec All Rights Reserved.
*
* Author:     chaigec <chaigec@163.com>
* Maintainer: chaigec <chaigec@163.com>

 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
*/

#include "MkUtil/MkUtil.h"
#include <gtest/gtest.h>

TEST(MkUtil, VersionTest)
{
    MkString Version;
    Uint32 ErrorCode = CMkUtil::GetVersion(Version);
    EXPECT_EQ(NoneError, ErrorCode);
    EXPECT_EQ(FALSE, Version.empty());
}

TEST(MkUtil, StringSplitTest)
{
    MkString tmp = "tmp/tmp/tmp";
    std::vector<MkString> Res;
    Uint32 ErrorCode = CMkUtil::StringSplit(tmp, "/", Res);
    EXPECT_EQ(NoneError, ErrorCode);
    EXPECT_EQ(3, Res.size());
}

TEST(MkUtil, RandomStringTest)
{
    MkString tmp;
    tmp = CMkUtil::CreateRandomString(100, tmp);
    EXPECT_EQ(tmp.size(), 100);
}

TEST(MkUtil, RandomNumber)
{
    for (int i=0;i<100;i++)
    {
       Uint32 RandNum = CMkUtil::GetRandomNumber();
    }
}

TEST(MkUtil, SocketTest)
{
    SOCKET ServerSock = CMkUtil::CreateListenSocket(45000);
    EXPECT_NE(ServerSock, -1);

    SOCKET ClientSock = CMkUtil::CreateClientSocket("127.0.0.1", 45000, 1000);
    EXPECT_NE(ClientSock, -1);

    closesocket(ServerSock);
    closesocket(ClientSock);
}

TEST(MkUtil, ThreadIdTest)
{
    Uint32 Id = CMkUtil::GetLocalThreadId();
    EXPECT_NE(Id, 0);
}

TEST(MkUtil, ReplaceTest)
{
    MkString str = "abcdef";
    MkString strRes;
    MkString strTmp = "abcabc";
    strRes = CMkUtil::Replace(str, "def", "abc");
    EXPECT_STREQ(strRes.c_str(), strTmp.c_str());
}

TEST(MkUtil, SplitPortTest)
{
    MkString strPort = "127.0.0.1:5555";
    MkString strHost;
    Uint16 Port = 0;
    Uint32 ErrorCode = CMkUtil::SplitPort(strPort, strHost, Port);
    EXPECT_EQ(ErrorCode, NoneError);
    EXPECT_EQ(Port, 5555);
    EXPECT_STREQ("127.0.0.1", strHost.c_str());
}

TEST(MkUtil, SplitPortTest2)
{
    MkString strPort = "5555";
    MkString strHost;
    Uint16 Port = 0;
    Uint32 ErrorCode = CMkUtil::SplitPort(strPort, strHost, Port);
    EXPECT_EQ(ErrorCode, NoneError);
    EXPECT_EQ(Port, 5555);
    EXPECT_STREQ("0.0.0.0", strHost.c_str());
}

TEST(MkUtil, SplitPortTest3)
{
    MkString strPort = "";
    MkString strHost;
    Uint16 Port = 0;
    Uint32 ErrorCode = CMkUtil::SplitPort(strPort, strHost, Port);
    EXPECT_NE(ErrorCode, NoneError);
}

TEST(MkUtil, SplitPortTest4)
{
    MkString strPort = "127.0.0.1:0";
    MkString strHost;
    Uint16 Port = 0;
    Uint32 ErrorCode = CMkUtil::SplitPort(strPort, strHost, Port);
    EXPECT_NE(ErrorCode, NoneError);
}

TEST(MkUtil, RegexTest)
{
    MkString strFrom = "abcdef";
    MkString strRegex = "de";
    MkString Res = CMkUtil::MyRegexReplace(strFrom, strRegex, "kkk");
    EXPECT_STREQ(Res.c_str(), "abckkkkkkf");
}

TEST(MkUtil, SafeStringTest)
{
    MkString str = CMkUtil::SafeMkString(nullptr);
    EXPECT_STREQ(str.c_str(), "");
}

TEST(MkUtil, SafeStringTest1)
{
    MkString str = CMkUtil::SafeMkString("123");
    EXPECT_STREQ(str.c_str(), "123");
}

TEST(MkUtil, SafeFloatTest)
{
    double ff = CMkUtil::SafeAtof(nullptr);
    EXPECT_EQ(ff, 0.0);
}

TEST(MkUtil, SafeFloatTest1)
{
    double ff = CMkUtil::SafeAtof("123");
    EXPECT_EQ(ff, 123.0);
}

TEST(MkUtil, SafeIntTest)
{
    Uint32 iRes = CMkUtil::SafeAtoi(nullptr);
    EXPECT_EQ(iRes, 0);
}

TEST(MkUtil, SafeIntTest1)
{
    Uint32 iRes = CMkUtil::SafeAtoi("123");
    EXPECT_EQ(iRes, 123);
}

TEST(MkUtil, UftGbkTest)
{
    /*MkString str = "你好";
    MkString strGbk;
    MkString strUtf;
    Uint32 ErrorCode = CMkUtil::Gbk2Utf8(str, strUtf);
    EXPECT_EQ(ErrorCode, NoneError);
    ErrorCode = CMkUtil::Utf8ToGbk(strUtf, strGbk);
    EXPECT_EQ(ErrorCode, NoneError);
    EXPECT_STREQ(str.c_str(), strGbk.c_str());*/
	MkString str = "你好";
    MkString strGbk;
    MkString strUtf;

   Uint32 ErrorCode = CMkUtil::Utf8ToGbk(str, strGbk);
    EXPECT_EQ(ErrorCode, NoneError);

     ErrorCode = CMkUtil::Gbk2Utf8(strGbk, strUtf);
    EXPECT_EQ(ErrorCode, NoneError);

    EXPECT_STREQ(str.c_str(), strUtf.c_str());
	
	ErrorCode = CMkUtil::Gbk2Utf8("", strUtf);
    EXPECT_EQ(ErrorCode, NoneError);

    str = "abcd,.sdfdwedf";
    ErrorCode = CMkUtil::Utf8ToGbk(str, strGbk);
    EXPECT_EQ(ErrorCode, NoneError);

    ErrorCode = CMkUtil::Gbk2Utf8(strGbk, strUtf);
    EXPECT_EQ(ErrorCode, NoneError);

    EXPECT_STREQ(str.c_str(), strUtf.c_str());

    str = "abcd,.双方都是";
    ErrorCode = CMkUtil::Utf8ToGbk(str, strGbk);
    EXPECT_EQ(ErrorCode, NoneError);

    ErrorCode = CMkUtil::Gbk2Utf8(strGbk, strUtf);
    EXPECT_EQ(ErrorCode, NoneError);

    EXPECT_STREQ(str.c_str(), strUtf.c_str());

    str = "abcd,.~@##》、nsdf";
    ErrorCode = CMkUtil::Utf8ToGbk(str, strGbk);
    EXPECT_EQ(ErrorCode, NoneError);

    ErrorCode = CMkUtil::Gbk2Utf8(strGbk, strUtf);
    EXPECT_EQ(ErrorCode, NoneError);

    EXPECT_STREQ(str.c_str(), strUtf.c_str());
}

TEST(MkUtil, CheckValidUrl)
{
    BOOL bRet = CMkUtil::CheckValidHttpUrl("http://127.0.0.1");
    EXPECT_EQ(bRet, TRUE);

    bRet = CMkUtil::CheckValidHttpUrl("httpaa://127.0.0.1");
    EXPECT_EQ(bRet, FALSE);

    bRet = CMkUtil::CheckVaildRtspUrl("rtsp://127.0.0.1");
    EXPECT_EQ(bRet, TRUE);

    bRet = CMkUtil::CheckVaildRtspUrl("httpaa://127.0.0.1");
    EXPECT_EQ(bRet, FALSE);

    bRet = CMkUtil::CheckVaildRtmpUrl("rtmp://127.0.0.1");
    EXPECT_EQ(bRet, TRUE);

    bRet = CMkUtil::CheckVaildRtmpUrl("httpaa://127.0.0.1");
    EXPECT_EQ(bRet, FALSE);

    MkString strHost;
    MkString Path;
    Uint16 Port;
    Uint32 ErrorCode = CMkUtil::HttpUrlParse("http://123.123.123.123:898/abc/abc", strHost, Port, Path);
    EXPECT_EQ(ErrorCode, NoneError);
    EXPECT_STREQ("123.123.123.123", strHost.c_str());
    EXPECT_EQ(Port, 898);
    EXPECT_STREQ("/abc/abc", Path.c_str());

    ErrorCode = CMkUtil::HttpUrlParse("http://123.123.123.124/abc", strHost, Port, Path);
    EXPECT_EQ(ErrorCode, NoneError);
    EXPECT_STREQ("123.123.123.124", strHost.c_str());
    EXPECT_EQ(Port, 80);
    EXPECT_STREQ("/abc", Path.c_str());

    ErrorCode = CMkUtil::HttpUrlParse("https://192.168.0.1:445/abc/abc?x=1111", strHost, Port, Path);
    EXPECT_EQ(ErrorCode, NoneError);
    EXPECT_STREQ("192.168.0.1", strHost.c_str());
    EXPECT_EQ(Port, 445);
    EXPECT_STREQ("/abc/abc?x=1111", Path.c_str());

    ErrorCode = CMkUtil::HttpUrlParse("https://192.168.0.2/abb/abc", strHost, Port, Path);
    EXPECT_EQ(ErrorCode, NoneError);
    EXPECT_STREQ("192.168.0.2", strHost.c_str());
    EXPECT_EQ(Port, 443);
    EXPECT_STREQ("/abb/abc", Path.c_str());

    ErrorCode = CMkUtil::RtmpUrlParse("rtmp://123.123.123.123:784/abc/abc", strHost, Port);
    EXPECT_EQ(ErrorCode, NoneError);
    EXPECT_STREQ("123.123.123.123", strHost.c_str());
    EXPECT_EQ(Port, 784);

    ErrorCode = CMkUtil::RtspUrlParse("rtsp://123.123.123.123:19911/abc/abc", strHost, Port);
    EXPECT_EQ(ErrorCode, NoneError);
    EXPECT_STREQ("123.123.123.123", strHost.c_str());
    EXPECT_EQ(Port, 19911);
}

TEST(MkUtil, ByteStringText)
{
    MkString strByte;
    CMkUtil::CreateRandomString(10, strByte);

    MkString strStr;
    CMkUtil::ByteToString((const Uint8 *)strByte.c_str(), strByte.size(), strStr);
    Uint8 pbuf[25] = { 0 };
    Uint32 nLen = 0;
    CMkUtil::StringToByte(strStr, pbuf, nLen);
    EXPECT_STREQ(strByte.c_str(), (char *)pbuf);

    std::transform(strStr.begin(), strStr.end(), strStr.begin(), ::tolower);
    Uint8 pbuf2[25] = { 0 };
    CMkUtil::StringToByte(strStr, pbuf2, nLen);
    EXPECT_STREQ(strByte.c_str(), (char *)pbuf2);
}

TEST(MkUtil, MkHttpUrlTest)
{
    MkString Res;
    Uint32 ErrorCode = CMkUtil::GetMkHttpUrl("http://127.0.0.1", Res);
    EXPECT_EQ(ErrorCode, NoneError);
    EXPECT_STREQ("http://127.0.0.1", Res.c_str());

    ErrorCode = CMkUtil::GetMkHttpUrl("http://127.0.0.1/", Res);
    EXPECT_EQ(ErrorCode, NoneError);
    EXPECT_STREQ("http://127.0.0.1", Res.c_str());
}

TEST(MkUtil, GetSystemCpuThreadNum)
{
    Uint32 CpuNum = 0;
    Uint32 ErrorCode = CMkUtil::GetSystemCpuThreadNum(CpuNum);
    EXPECT_EQ(ErrorCode, NoneError);
    EXPECT_NE(0, CpuNum);
}

TEST(MkUtil, CheckHttpUrlConnectAbled)
{
    SOCKET Socket = CMkUtil::CreateListenSocket(45634);
    if (INVALID_SOCKET != Socket) {
        MkString HttpUrl = "http://127.0.0.1:45634/api/v1/tmp";
        Uint32 ErrorCode = CMkUtil::CheckHttpUrlConnectAbled(HttpUrl);
        EXPECT_EQ(ErrorCode, NoneError);
        closesocket(Socket);
    }
}

TEST(MkUtil, GetLocalIp)
{
    MkString LocalIp;
    Uint32 ErrorCode = CMkUtil::GetLocalIp(LocalIp);
    EXPECT_EQ(ErrorCode, NoneError);
    EXPECT_NE(LocalIp.empty(), TRUE);
}

TEST(MkUtil, StringToAscii)
{
    MkString str = "%120.sfsd&aa\n";
    MkString strAscii;
    Uint32 ErrorCode = CMkUtil::StringToAscii(str, strAscii);
    EXPECT_EQ(ErrorCode, NoneError);
    EXPECT_NE(strAscii.empty(), TRUE);
}

TEST(MkUtil, Hex)
{
    Uint8 Tmp = '1';
    Uint8 Tmp2 = '\n';
    EXPECT_EQ(TRUE, CMkUtil::IsHex(Tmp));
    EXPECT_NE(TRUE, CMkUtil::IsHex(Tmp2));
}

TEST(MkUtil, ReadLine)
{
    MkString Content = "1\n";
    Content += "2\r\n";
    Content += "3\r";
    Content += "4";

    Uint32 nPos = 0;
    MkString strLine;
    Uint32 ErrorCode = CMkUtil::BufferReadLine(Content, nPos, strLine);
    EXPECT_EQ(ErrorCode, NoneError);
    EXPECT_STREQ("1", strLine.c_str());
    strLine.clear();

    ErrorCode = CMkUtil::BufferReadLine(Content, nPos, strLine);
    EXPECT_EQ(ErrorCode, NoneError);
    EXPECT_STREQ("2", strLine.c_str());
    strLine.clear();

    ErrorCode = CMkUtil::BufferReadLine(Content, nPos, strLine);
    EXPECT_NE(ErrorCode, NoneError);
}

TEST(MkUtil, CheckUdpIsUseAbled)
{
    SOCKET Sock = CMkUtil::CreateListenSocket(45676, FALSE);
    if (INVALID_SOCKET != Sock) {
        Uint32 ErrorCode = CMkUtil::CheckUdpIsUseAbled(45676);
        EXPECT_NE(NoneError, ErrorCode);
        closesocket(Sock);
        ErrorCode = CMkUtil::CheckUdpIsUseAbled(45676);
        EXPECT_EQ(ErrorCode, NoneError);
    }
}

TEST(MkUtil, CheckTcpIsUseAbled)
{
    SOCKET Sock = CMkUtil::CreateListenSocket(45676, TRUE);
    if (INVALID_SOCKET != Sock) {
        Uint32 ErrorCode = CMkUtil::CheckTcpIsUseAbled(45676);
        EXPECT_NE(NoneError, ErrorCode);
        closesocket(Sock);
        ErrorCode = CMkUtil::CheckTcpIsUseAbled(45676);
        EXPECT_EQ(NoneError, ErrorCode);
    }
}

TEST(MkUtil, FreeTcpPort)
{
    Uint16 TcpPort = 0;
    Uint32 ErrorCode = CMkUtil::GetFreeTcpPort(60000, 61000, 60000, TcpPort);
    EXPECT_EQ(NoneError, ErrorCode);
    EXPECT_NE(0, TcpPort);

    ErrorCode = CMkUtil::GetFreeTcpPort(60000, 61000, 61000, TcpPort);
    EXPECT_EQ(NoneError, ErrorCode);
    EXPECT_NE(0, TcpPort);
}

TEST(MkUtil, FreeUdpPort)
{
    Uint16 UdpPort = 0;
    Uint32 ErrorCode = CMkUtil::GetFreeUdpPort(60000, 61000, 60050, UdpPort);
    EXPECT_EQ(NoneError, ErrorCode);
    EXPECT_NE(0, UdpPort);

    ErrorCode = CMkUtil::GetFreeUdpPort(60000, 61000, 61000, UdpPort);
    EXPECT_EQ(NoneError, ErrorCode);
    EXPECT_NE(0, UdpPort);
}

TEST(MkUtil, ReadByte)
{
    Uint64 Tmp64 = ((Uint64)CMkUtil::GetRandomNumber() << 32) | CMkUtil::GetRandomNumber();
    Uint32 Tmp32 = CMkUtil::GetRandomNumber();
    Uint32 Tmp24 = CMkUtil::GetRandomNumber() & 0xFFFFFF;
    Uint16 Tmp16 = CMkUtil::GetRandomNumber() & 0xFFFF;
    Uint8  Tmp8 = CMkUtil::GetRandomNumber() & 0xFF;
    Uint8 pBuf[Len1K] = { 0 };
    Uint32 nOffset = 0;
    CMkUtil::Packet64Bit(pBuf, nOffset, Tmp64);
    CMkUtil::Packet24Bit(pBuf, nOffset, Tmp24);
    CMkUtil::Packet8Bit(pBuf, nOffset, Tmp8);
    CMkUtil::Packet32Bit(pBuf, nOffset, Tmp32);
    EXPECT_EQ(16, nOffset);
    nOffset = 0;
    EXPECT_EQ(Tmp64, CMkUtil::Read64Bit(pBuf, nOffset));
    EXPECT_EQ(Tmp24, CMkUtil::Read24Bit(pBuf, nOffset));
    EXPECT_EQ(Tmp8, CMkUtil::Read8Bit(pBuf, nOffset));
    EXPECT_EQ(Tmp32, CMkUtil::Read32Bit(pBuf, nOffset));
}